package cn.wuyi.common.eureka.server.config;

import java.util.function.Consumer;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.Config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.handler.AsyncPredicate;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.reactive.CorsWebFilter;

import reactor.core.publisher.Mono;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.util.pattern.PathPatternParser;

@Configuration
public class RedisRateLimiterConfig {

//    KeyResolver userKeyResolver() {
//        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
//    }
//	
	@Bean
	public KeyResolver ipKeyResolver() {
	    return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
	}
	
	@Bean
    @Order(-1)
    public GlobalFilter firstFilter()
    {
        return (exchange, chain) -> {
            System.out.println("The first filter !");
            
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                System.out.println("first pass filter");
            }));
        };
    }
    
    @Bean
    @Order(0)
    public GlobalFilter secondFilter()
    {
        return (exchange, chain) -> {
            System.out.println("The second filter !");
            
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                System.out.println("second pass filter");
            }));
        };
    }
    
    @Value("${test.uri}")
    private String uri;

    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
       
    	Config c=new Config();
    	c.setRouteId("base_route");
        Consumer<Config> consumer_fun_after = Config->    	c.setKeyResolver(ipKeyResolver());
        consumer_fun_after.accept(c);
        
		AsyncPredicate<ServerWebExchange> predicate = null;
		GatewayFilter gatewayFilter;
		return builder.routes()
				.route("base_route", r -> r.path("/**")
						.uri(uri))
				.build();
    }
    @Bean
	public RouteLocator path_route(RouteLocatorBuilder builder) {
		return builder.routes()
				.route("path_route", r -> r.path("/about")
						.uri("http://ityouknow.com"))
				.build();
	}
    
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();

        config.setAllowCredentials(true); // 允许cookies跨域
        config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI，*表示全部允许，在SpringMVC中，如果设成*，会自动转成当前请求头中的Origin
        config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
        config.addAllowedMethod("*");// 允许提交请求的方法类型，*表示全部允许
        config.setMaxAge(18000L);// 预检请求的缓存时间（秒），即在这个时间段里，对于相同的跨域请求不会再预检了

        org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource source =
                new org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);

        return new CorsWebFilter(source);
    }

}